# ifndef __WTR_H_
# define __WTR_H_

# include "fvector.h"

//
// The attached waypoints/tracks/routes additional info.
//

enum wtr_type {
	wtrWaypoint = 0,
	wtrRoute    = 1,
	wtrTrack    = 2, 
};

struct wtr_base_t {
	const wtr_type type;

	wtr_base_t (wtr_type _type) : type (_type) {}
	virtual ~wtr_base_t () {}

	virtual wtr_base_t * clone () const = 0;
};

struct waypoint_info_t : public wtr_base_t {
	waypoint_info_t () : wtr_base_t (wtrWaypoint), wFlags (0) {}

	string_t strURL;
	string_t strRoutingDirections;

	DATE  dtTime;
	float fAltitude;    // In m.
	float fProximity;   // In m.
	float fDepth;       // In m.
	float fTemperature; // In Celsius degrees.

	COLORREF colText;
	COLORREF colBack;

	enum {
		defShowMask     = 0x0003,

		defTime         = 0x0004,
		defAltitude     = 0x0008,
		defProximity    = 0x0010,
		defDepth        = 0x0020,
		defTemperature  = 0x0040,
		defGarminType   = 0x0080,

		defTextColor    = 0x0100,
		defBackColor    = 0x0200,

		defTmpBit       = 0x8000 // NOTE: used for tmp marking purposes.
	};
	WORD wFlags;

	WORD wGarminType;

	enum show_t {
		showName        = 0x0, // Symbol & Name (default)
		showDescription = 0x1, // Symbol & Description
		showSymbol      = 0x2, // Symbol only
		showHide        = 0x3,
	};
	void SetShow (show_t _show) {wFlags = (wFlags & ~defShowMask) | WORD (_show);}
	show_t GetShow () const {return static_cast<show_t> (wFlags & defShowMask);}

	// Override.
	virtual wtr_base_t * clone () const {return new waypoint_info_t (* this);}
};

//////////////////////////

struct rgn_t;

struct routepoint_info_t {
	routepoint_info_t () : pWaypoint (NULL) {}

	rgn_t * pWaypoint;
};

typedef fvector<routepoint_info_t> routepoints_t;

struct route_info_t : public wtr_base_t {
	route_info_t () : wtr_base_t (wtrRoute), wFlags (0) {}

	string_t strURL;
	DATE  dtTime;
	COLORREF colLine;

	routepoints_t points;

	enum {
		defTime      = 0x01,
		defAutoName  = 0x02,
		defLineColor = 0x04,
		defHideLabel = 0x08,
	};
	WORD wFlags;

	WORD wReserved;

	// Override.
	virtual wtr_base_t * clone () const {return new route_info_t (* this);}
};

//////////////////////////

struct trackpoint_info_t {
	trackpoint_info_t () : wFlags (0) {}

	DATE  dtTime;
	float fAltitude;    // In m.
	float fSpeed;       // In km/h.
	float fDepth;       // In m.
	float fTemperature; // In Celsius degrees.
	float fDOP;

	enum {
		defTime             = 0x01,
		defTimeMilliseconds = 0x02, // In addition to defTime
		defAltitude         = 0x04,
		defSpeed            = 0x08,
		defDepth            = 0x10,
		defTemperature      = 0x20,
		defDOP              = 0x40,
	};
	WORD wFlags;

	WORD wReserved;
};

typedef fvector<trackpoint_info_t> trackpoints_t;

# include "PtAlgo.h"

struct track_info_t : public wtr_base_t {
	track_info_t () : wtr_base_t (wtrTrack), wFlags (0) {}

	string_t strURL;
	COLORREF colLine;

//	trackpoints_t points;
//	float GetSpeed (size_t _cPoint, const points_t & _points) const;

	enum {
		defHideInGPS = 0x01,
		defLineColor = 0x02,
		defLineWidth = 0x04,
	};
	WORD wFlags;

	WORD wLineWidth;

	// Override.
	virtual wtr_base_t * clone () const {return new track_info_t (* this);}
};

//////////////////////////////

struct wtr_extra_t {
	wtr_extra_t () : p (NULL) {}
	wtr_extra_t (const wtr_extra_t & _other) : p (_other.p != NULL ? _other.p->clone () : NULL) {}
	~wtr_extra_t () {delete p;}

	bool empty () const {return p != NULL;}

	waypoint_info_t * CreateWaypoint () {
		assert (p == NULL);
		p = new waypoint_info_t;
		return wpt ();
	}
	track_info_t * CreateTrack () {
		assert (p == NULL);
		p = new track_info_t;
		return track ();
	}
	route_info_t * CreateRoute () {
		assert (p == NULL);
		p = new route_info_t;
		return route ();
	}

	wtr_extra_t & operator = (const wtr_extra_t & _other) {
		if (this == & _other)
			return * this;
		delete p;
		if (_other.p)
			p = _other.p->clone ();
		return * this;
	}

	const waypoint_info_t * wpt () const {assert (p->type == wtrWaypoint); return static_cast<const waypoint_info_t *> (p);}
	      waypoint_info_t * wpt ()       {assert (p->type == wtrWaypoint); return static_cast<      waypoint_info_t *> (p);}
	const track_info_t  * track () const {assert (p->type == wtrTrack);    return static_cast<const track_info_t *> (p);}
	      track_info_t  * track ()       {assert (p->type == wtrTrack);    return static_cast<      track_info_t *> (p);}
	const route_info_t  * route () const {assert (p->type == wtrRoute);    return static_cast<const route_info_t *> (p);}
	      route_info_t  * route ()       {assert (p->type == wtrRoute);    return static_cast<      route_info_t *> (p);}

  private:
	wtr_base_t * p;
};

# endif // __WTR_H_